﻿namespace nBayes
{
    using System.Collections.Generic;
    using System.Xml.Serialization;

    /// <remarks>Original code found here: http://weblogs.asp.net/pwelter34/archive/2006/05/03/444961.aspx</remarks>
    [XmlRoot("index")]
    public class IndexTable<TKey, TValue>
        : Dictionary<TKey, TValue>, IXmlSerializable
    {
        private static object synclock = new object();
        #region IXmlSerializable Members
        public System.Xml.Schema.XmlSchema GetSchema()
        {
            return null;
        }

        public void ReadXml(System.Xml.XmlReader reader)
        {
            lock (synclock)
            {
                XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
                XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));

                bool wasEmpty = reader.IsEmptyElement;
                reader.Read();

                if (wasEmpty)
                    return;

                while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
                {
                    reader.ReadStartElement("entry");

                    reader.ReadStartElement("word");
                    TKey key = (TKey)keySerializer.Deserialize(reader);
                    reader.ReadEndElement();

                    reader.ReadStartElement("count");
                    TValue value = (TValue)valueSerializer.Deserialize(reader);
                    reader.ReadEndElement();

                    this.Add(key, value);

                    reader.ReadEndElement();
                    reader.MoveToContent();
                }
                reader.ReadEndElement();
            }
        }

        public void WriteXml(System.Xml.XmlWriter writer)
        {
            lock (synclock)
            {
                XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
                XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));
                lock (Keys)
                {
                    foreach (TKey key in this.Keys)
                    {
                        writer.WriteStartElement("entry");

                        writer.WriteStartElement("word");
                        keySerializer.Serialize(writer, key);
                        writer.WriteEndElement();

                        writer.WriteStartElement("count");
                        TValue value = this[key];
                        valueSerializer.Serialize(writer, value);
                        writer.WriteEndElement();

                        writer.WriteEndElement();
                    }
                }
            }
        }
        #endregion
    }
}